﻿using System;


namespace BlamanticUI.Components.Forms;

/// <summary>
/// Represents a &lt;input type="radio" /> form control.
/// </summary>
/// <typeparam name="TValue">The type of the value.</typeparam>
public class RadioBox<TValue> : BlazorChildComponentBase<RadioGroup<TValue>>, IHasUIComponent,IHasChildContent, IDisposable
{
    /// <summary>
    /// Gets or sets the value.
    /// </summary>
    [Parameter] public TValue? Value { get; set; }

    /// <summary>
    /// A segment of UI content behind radio input control.
    /// </summary>
    [Parameter]public RenderFragment? ChildContent { get; set; }

    protected override void OnInitialized()
    {
        base.ThrowIfParentComponentNull();

        if (Value?.GetType() != typeof(TValue))
        {
            throw new InvalidOperationException($"The type of {nameof(this.Value)} should be the same type of {typeof(RadioBox<>).FullName}");
        }

        ParentComponent.RerenderRadioBoxes += StateHasChanged;
    }

    /// <summary>
    /// Renders the component to the supplied <see cref="T:Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder" />.
    /// </summary>
    /// <param name="builder">A <see cref="T:Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder" /> that will receive the render output.</param>
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.CreateElement(0, "div", field =>
        {
            field.OpenElement(0, "div");
            BuildComponentAttributes(field, out var sequence);
            field.AddContent(sequence + 1, child =>
            {
                child.CreateElement(0, "label", label =>
                {
                    label.CreateElement(0, "input", attributes: new
                    {
                        type = "radio",
                        value = BindConverter.FormatValue(Value)?.ToString(),
                        name = ParentComponent.Name,
                        @checked = Checked,
                        onchange = ParentComponent.ChangeEventCallback
                    });
                    label.AddContent(1, ChildContent);
                }, new { style = "cursor:pointer" });
            });
            field.CloseElement();
        }, new { @class = "field" });
    }

    protected override void BuildCssClass(ICssClassBuilder builder)
    {
        builder.Append("checked", Checked.HasValue && Checked.Value)
            .Append("radio checkbox")
            ;
    }

    public void Dispose()
    {
        if (ParentComponent != null)
        {
            ParentComponent.RerenderRadioBoxes -= StateHasChanged;
        }
    }

    /// <summary>
    /// Gets the checked.
    /// </summary>
    /// <value>
    /// The checked.
    /// </value>
    bool? Checked => ParentComponent?.SelectedValue?.Equals(Value);
}
